package com.tth.learn.addproperties.java;

import org.junit.Test;

import java.util.Random;

/**
 * 通过反射创建对应的运行时类对象
 * @Author tth
 * @Date 2022/12/29 15:31
 */
public class NewInstanceTest {

    @Test
    public void test1() throws IllegalAccessException, InstantiationException {
        Class<Person> clazz = Person.class;

        /**
         * newInstance()：创建对应的运行时类。内部调用了运行时类的空参构造器
         *
         * 使用newInstance()的要求：
         *  1.运行时类必须有空参构造器，否则会报InstantiationException异常
         *  2.空参构造器的访问权限得够。可以为缺省、protected、public，通常设置为public。
         *
         * 在JavaBean中要求提供一个public的空参构造器，原因：
         *  1.便于通过反射，创建运行时类的对象
         *  2.便于子类继承此运行时类，默认调用super()时，保证父类有此构造器
         */
        Person person = clazz.newInstance();
        System.out.println(person);
    }

    /**
     * 体会反射的动态性
     */
    @Test
    public void test2() {
        for (int i = 0; i < 100; i++) {
            int num = new Random().nextInt(3);// 随机生成0、1、2
            String classpath = "";
            switch (num) {
                case 0:
                    classpath = "java.util.Date";
                    break;
                case 1:
                    classpath = "java.lang.Object";
                    break;
                case 2:
                    classpath = "com.tth.learn.java.Person";
                    break;
            }

            try {
                Object obj = getInstance(classpath);
                System.out.println(obj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取类对象
     * @param classpath 类的完整类名
     * @return
     * @throws Exception
     */
    private Object getInstance(String classpath) throws Exception{
        Class<?> clazz = Class.forName(classpath);
        return clazz.newInstance();
    }

}
